package com.seirsoft.framework.payload;

import java.lang.reflect.Type;
import java.text.DateFormat;
import java.util.Date;

import com.seirsoft.framework.util.DateUtil;
public class PayloadRow 
{
    // Fields
    private int[] m_ints;
    private Object[] m_values;
    private static Object s_data = new Object();

	private PayloadTable m_Parent = null;
	
	protected PayloadRow(PayloadTable parent)
	{
		m_Parent = parent;
		
		PayloadColumnCollection columns = this.m_Parent.getColumns();
		
        this.m_values = new Object[columns.getCount()];
        for (int i = 0; i < this.m_values.length; i++)
        {
            this.m_values[i] = null;
        }
        
        if (columns.getIntCount() != 0)
        {
            this.m_ints = new int[columns.getIntCount()];
        }
	}
	
	public void setValue(int iIndex, String s) throws Exception
	{
    	PayloadColumn column = this.m_Parent.getColumns().get(iIndex);
    	
        Type dataType = column.getDataType();

        if (column.getIsValue())
        {
            if (dataType.equals(int.class))
            {
            	this.m_ints[column.getOffset()] = Integer.valueOf(s);
            }
            else
            {
                if (!dataType.equals(boolean.class))
                {
                    throw new Exception("UnexpectedColumnType:" + dataType.toString() );
                }
                this.m_ints[column.getOffset()] = Boolean.valueOf(s) ? 1 : 0;
            }
            this.m_values[iIndex] = s_data;
        }
        else if (dataType.equals(String.class))
        {
        	this.m_values[iIndex] = s;
        }
        else if (dataType.equals(Date.class))
        {
        	// C#: object.m_values[j] = Date.valueOf(s, @"yyyy-MM-dd\THH:mm:ss.fff", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
        	DateFormat format = DateUtil.getDateFormat();
        	this.m_values[iIndex] = format.parse(s);
        }
        else if (dataType.equals(long.class))
        {
        	this.m_values[iIndex] = Long.valueOf(s);
        }
        else if (dataType.equals(double.class))
        {
        	this.m_values[iIndex] = Double.valueOf(s);
        }
        else
        {
            //if (!dataType.equals(typeof(Guid)))
            {
            ///    throw new FormatException(ResourceStrings.Format("UnexpectedColumnType", new object[] { dataType.FullName }));
            }
            //this.m_values[j] = new Guid(s);
        }
	}
	
	public PayloadTable getTable()
	{
		return this.m_Parent;
	}
	
	public Object getColumn(int index) throws Exception
	{
        if (((index < 0) || (this.m_values == null)) || (index >= this.m_values.length))
        {
            throw new Exception("index out of range.");
        }
        
        if(this.m_values[index] == null)
        {
        	return null;
        }
        
        if (! this.m_values[index].equals(s_data))
        {
            return this.m_values[index];
        }
        
        PayloadColumn column = this.m_Parent.getColumns().get(index);
        Type dataType = column.getDataType();
        if (dataType.equals(int.class))
        {
            return this.m_ints[column.getOffset()];
        }
        if (!dataType.equals(boolean.class))
        {
            throw new Exception("boolean format error.");
        }
        return (this.m_ints[column.getOffset()] != 0);
 		
	}
	
    /**
     *  Factory class that keeps the parse method
     */
    public static class Factory {
        /**
         * static method to create the object
         * Precondition:  If this object is an element, the current or next start element starts this object and any intervening reader events are ignorable
         *                If this object is not an element, it is a complex type and the reader is at the event just after the outer start element
         * Postcondition: If this object is an element, the reader is positioned at its end element
         *                If this object is a complex type, the reader is positioned at the end element of its outer element
         */
        public static PayloadRow parse(
            javax.xml.stream.XMLStreamReader reader,
            PayloadTable parent) throws java.lang.Exception {
        	
        	PayloadRow object = new PayloadRow(parent);

            try {

            	
                while (!reader.isStartElement() && !reader.isEndElement())
                    reader.next();


                
                
    			// get Next Element: <f> or </r>
                do{
                	reader.next();
                } while (!reader.isStartElement() && !reader.isEndElement());
                
                for (int j=0; reader.isStartElement(); j++)
                {
            		if(reader.getLocalName().equals("f"))
            		{
            			if(reader.getAttributeCount() > 0)
            			{
            				String attribute = reader.getAttributeValue("", "k");
            				if(attribute != null && attribute.equals("") == false)
            				{
            					j = Integer.parseInt(attribute);
            				}
            			}
            			
                        
                        String s = null;
                        if (reader.isWhiteSpace())
                        {
                            s = "";
                        }
                        else
                        {
                            s = reader.getElementText();
                        }
                        if (s != null)
                        {
                        	object.setValue(j, s);
                        }

                        while (!reader.isEndElement())
	                    {
	                    	reader.next();
	                    }
            		}
            		else
            		{
            			// </Unkown>
	                    do{
	                    	reader.next();
	                    } while (!reader.isStartElement() && !reader.isEndElement());
            		}
            		
            		// get next Element: <f> or </r>
                    do{
                    	reader.next();
                    } while (!reader.isStartElement() && !reader.isEndElement());
                }
            } catch (javax.xml.stream.XMLStreamException e) {
                throw new java.lang.Exception(e);
            }

            return object;
        }
    } //end of factory class

}
